package moa.sequencestreams.generator;

import org.apache.commons.math.random.RandomDataImpl;


public class Taxonomy {
	private int nitems;	// number of items
	private int nroots;	// number of roots
	private float depth;	// used when assigning probabilities to items

	private int [] par;
	private int [] child_start;
	private int [] child_end;

	//static const int item_len;  // ASCII field-width of item-id
		
	/*public void write(ofstream &fp);		// write taxonomy to file
	public void write_asc(ofstream &fp);	// write taxonomy to ASCII file
	public void display(ofstream &fp);	// display taxonomy (for user)
*/
	public float depth_ratio() 
	{ return depth; }
	
	public int num_roots() 
	{ return nroots; }
	
	public boolean root(int itm) 
	{ return (par[itm] == -1); }

	public int num_children(int itm) 
	{ return child_end[itm] -  child_start[itm]; }
	
	public int child(int itm, int n) 
	{ return child_start[itm]+n; }
	
	public int first_child(int itm) 
	{ return child_start[itm]; }
	
	public int last_child(int itm) 
	{ return child_end[itm]-1; }

	public int parent(int itm) { 
		return par[itm]; 
	}	
	
	public Taxonomy (int num_items, int num_roots, float fanout, float depth_ratio)
	{
		nitems = num_items;
		nroots = num_roots;
		depth = depth_ratio;
		RandomDataImpl rd = new RandomDataImpl();
		
		int i, j;
		int next_child ;
		//PoissonDist nchildren = new PoissonDist (fanout-1);	// string length

		// allocate memory
		  par = new int [nitems];
		  child_start = new int [nitems];
		  child_end = new int [nitems];

		  next_child = nroots;
		
		  // initialize parents (or lack thereof) for roots
		  for (i = 0; i < nroots; i++)
		    par[i] = -1;
		  
		  // set up all the interior nodes
		  for (i = 0, j = next_child; i < nitems && next_child < nitems; i++)
		    {
		      child_start[i] = next_child;
		      next_child += rd.nextPoisson(fanout-1) + 1;
		      if (next_child > nitems) 
			next_child = nitems;
		      child_end[i] = next_child;
		      for (; j < next_child; j++)
			par[j] = i;
		    }

		  // initialize children (or lack thereof) for all the leaves
		  for (; i < nitems; i++)
		    child_start[i] = 
		    child_end[i] = -1;		  
		  
	}
}
